package com.sugar.psych.assessment.module.business.service.userpsychassessmentrecord;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.sugar.psych.assessment.framework.common.util.json.JsonUtils;
import com.sugar.psych.assessment.framework.dict.core.DictFrameworkUtils;
import com.sugar.psych.assessment.framework.mybatis.core.dataobject.BaseDO;
import com.sugar.psych.assessment.framework.mybatis.core.util.MyBatisUtils;
import com.sugar.psych.assessment.module.business.controller.admin.userpointsrecord.vo.UserPointsRecordSaveReqVO;
import com.sugar.psych.assessment.module.business.controller.app.userpsychassessmentrecord.vo.*;
import com.sugar.psych.assessment.module.business.dal.dataobject.basicconfig.BasicConfigDO;
import com.sugar.psych.assessment.module.business.dal.dataobject.configrisklevel.ConfigRiskLevelDO;
import com.sugar.psych.assessment.module.business.dal.dataobject.psychquestion.PsychQuestionDO;
import com.sugar.psych.assessment.module.business.dal.dataobject.psychquestionbank.PsychQuestionBankDO;
import com.sugar.psych.assessment.module.business.dal.dataobject.school.SchoolDO;
import com.sugar.psych.assessment.module.business.dal.dataobject.user.UserDO;
import com.sugar.psych.assessment.module.business.dal.dataobject.userpsychassessmentrecord.UserPsychQuestionRecordDO;
import com.sugar.psych.assessment.module.business.dal.mysql.basicconfig.BasicConfigMapper;
import com.sugar.psych.assessment.module.business.dal.mysql.configrisklevel.ConfigRiskLevelMapper;
import com.sugar.psych.assessment.module.business.dal.mysql.psychquestion.PsychQuestionMapper;
import com.sugar.psych.assessment.module.business.dal.mysql.psychquestionbank.PsychQuestionBankMapper;
import com.sugar.psych.assessment.module.business.dal.mysql.school.SchoolMapper;
import com.sugar.psych.assessment.module.business.dal.mysql.user.BizUserMapper;
import com.sugar.psych.assessment.module.business.dal.mysql.userpsychassessmentrecord.UserPsychQuestionRecordMapper;
import com.sugar.psych.assessment.module.business.service.userpointsrecord.UserPointsRecordService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

import org.springframework.validation.annotation.Validated;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

import com.sugar.psych.assessment.module.business.controller.admin.userpsychassessmentrecord.vo.*;
import com.sugar.psych.assessment.module.business.dal.dataobject.userpsychassessmentrecord.UserPsychAssessmentRecordDO;
import com.sugar.psych.assessment.framework.common.pojo.PageResult;
import com.sugar.psych.assessment.framework.common.pojo.PageParam;
import com.sugar.psych.assessment.framework.common.util.object.BeanUtils;

import com.sugar.psych.assessment.module.business.dal.mysql.userpsychassessmentrecord.UserPsychAssessmentRecordMapper;

import static com.sugar.psych.assessment.framework.common.exception.util.ServiceExceptionUtil.exception;
import static com.sugar.psych.assessment.module.business.enums.ErrorCodeConstants.*;
import static com.sugar.psych.assessment.module.business.enums.PointRecordClsEnum.CLS4;

/**
 * 用户心理测评记录 Service 实现类
 *
 * @author Ysugar
 */
@Slf4j
@Service
@Validated
public class UserPsychAssessmentRecordServiceImpl implements UserPsychAssessmentRecordService {

    @Resource
    private UserPsychAssessmentRecordMapper userPsychAssessmentRecordMapper;
    @Resource
    private UserPsychQuestionRecordMapper userPsychQuestionRecordMapper;
    @Resource
    private PsychQuestionBankMapper psychQuestionBankMapper;
    @Resource
    private PsychQuestionMapper psychQuestionMapper;
    @Resource
    private ConfigRiskLevelMapper configRiskLevelMapper;
    @Resource
    private UserPointsRecordService userPointsRecordService;
    @Resource
    private BasicConfigMapper basicConfigMapper;
    @Resource
    private BizUserMapper bizUserMapper;
    @Resource
    private SchoolMapper schoolMapper;

    @Override
    public Long createUserPsychAssessmentRecord(UserPsychAssessmentRecordSaveReqVO createReqVO) {
        // 插入
        UserPsychAssessmentRecordDO userPsychAssessmentRecord = BeanUtils.toBean(createReqVO, UserPsychAssessmentRecordDO.class);
        userPsychAssessmentRecordMapper.insert(userPsychAssessmentRecord);
        // 返回
        return userPsychAssessmentRecord.getId();
    }

    @Override
    public void updateUserPsychAssessmentRecord(UserPsychAssessmentRecordSaveReqVO updateReqVO) {
        // 校验存在
        validateUserPsychAssessmentRecordExists(updateReqVO.getId());
        // 更新
        UserPsychAssessmentRecordDO updateObj = BeanUtils.toBean(updateReqVO, UserPsychAssessmentRecordDO.class);
        userPsychAssessmentRecordMapper.updateById(updateObj);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteUserPsychAssessmentRecord(Long id) {
        // 校验存在
        validateUserPsychAssessmentRecordExists(id);
        // 删除
        userPsychAssessmentRecordMapper.deleteById(id);

        // 删除子表
        deleteUserPsychQuestionRecordByRecordId(id);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteUserPsychAssessmentRecordListByIds(List<Long> ids) {
        // 校验存在
        validateUserPsychAssessmentRecordExists(ids);
        // 删除
        userPsychAssessmentRecordMapper.deleteByIds(ids);

        // 删除子表
        deleteUserPsychQuestionRecordByRecordIds(ids);
    }

    private void validateUserPsychAssessmentRecordExists(List<Long> ids) {
        List<UserPsychAssessmentRecordDO> list = userPsychAssessmentRecordMapper.selectByIds(ids);
        if (CollUtil.isEmpty(list) || list.size() != ids.size()) {
            throw exception(USER_PSYCH_ASSESSMENT_RECORD_NOT_EXISTS);
        }
    }

    private void validateUserPsychAssessmentRecordExists(Long id) {
        if (userPsychAssessmentRecordMapper.selectById(id) == null) {
            throw exception(USER_PSYCH_ASSESSMENT_RECORD_NOT_EXISTS);
        }
    }

    @Override
    public UserPsychAssessmentRecordDO getUserPsychAssessmentRecord(Long id) {
        return userPsychAssessmentRecordMapper.selectById(id);
    }

    @Override
    public PageResult<UserPsychAssessmentRecordDO> getUserPsychAssessmentRecordPage(UserPsychAssessmentRecordPageReqVO pageReqVO) {
        return userPsychAssessmentRecordMapper.selectPage(pageReqVO);
    }

    // ==================== 子表（用户心理测评题目表） ====================

    @Override
    public PageResult<UserPsychQuestionRecordDO> getUserPsychQuestionRecordPage(PageParam pageReqVO, Long recordId) {
        return userPsychQuestionRecordMapper.selectPage(pageReqVO, recordId);
    }

    @Override
    public Long createUserPsychQuestionRecord(UserPsychQuestionRecordDO userPsychQuestionRecord) {
        userPsychQuestionRecordMapper.insert(userPsychQuestionRecord);
        return userPsychQuestionRecord.getId();
    }

    @Override
    public void updateUserPsychQuestionRecord(UserPsychQuestionRecordDO userPsychQuestionRecord) {
        // 校验存在
        validateUserPsychQuestionRecordExists(userPsychQuestionRecord.getId());
        // 更新
        userPsychQuestionRecord.clean(); // 解决更新情况下：updateTime 不更新
        userPsychQuestionRecordMapper.updateById(userPsychQuestionRecord);
    }

    @Override
    public void deleteUserPsychQuestionRecord(Long id) {
        // 删除
        userPsychQuestionRecordMapper.deleteById(id);
    }

    @Override
    public void deleteUserPsychQuestionRecordListByIds(List<Long> ids) {
        // 删除
        userPsychQuestionRecordMapper.deleteByIds(ids);
    }

    @Override
    public UserPsychQuestionRecordDO getUserPsychQuestionRecord(Long id) {
        return userPsychQuestionRecordMapper.selectById(id);
    }

    @Override
    public Long appUserCreate(Long loginUserId) {
        // 判断当前用户是否已经答过首套试题
        Long count = userPsychAssessmentRecordMapper.selectCount(UserPsychAssessmentRecordDO::getUserId, loginUserId);
        if (count >= 1)
            throw exception(USER_PSYCH_QUESTION_RECORD_HAVE_TOP);

        // 查询首套题库
        PsychQuestionBankDO firstBank = psychQuestionBankMapper.selectOne(Wrappers.<PsychQuestionBankDO>lambdaQuery()
                .eq(PsychQuestionBankDO::getRiskLevel, 0)
                .eq(PsychQuestionBankDO::getStatus, 0)
                .nested(w -> w.isNull(PsychQuestionBankDO::getValidTime).or().ge(PsychQuestionBankDO::getValidTime, LocalDateTime.now()))
                .orderByDesc(PsychQuestionBankDO::getIsTop, BaseDO::getUpdateTime)
                .last("LIMIT 1"));

        if (Objects.isNull(firstBank))
            throw exception(PSYCH_QUESTION_BANK_NOT_EXISTS_APP);

        // 查询当前题库的试题
        List<PsychQuestionDO> questions = psychQuestionMapper.selectList(PsychQuestionDO::getBankId, firstBank.getId());
        if (CollUtil.isEmpty(questions))
            throw exception(PSYCH_QUESTION_IS_EMPTY);

        List<PsychQuestionDO> selectQuestions = new ArrayList<>();
        // 如果当前题库里的题目 <= 待取数量，则直接将这几道题返回
        Integer extractCount = firstBank.getExtractCount();
        if (questions.size() <= extractCount)
            selectQuestions = questions;
        else {
            Boolean extractType = firstBank.getExtractType();
            if (extractType) {
                // 根据提取数量遍历
                for (int i = 0; i < extractCount; i++) {
                    // 计算剩余的提取次数
                    int remaining = extractCount - i;
                    // 计算随机数
                    int index = RandomUtil.randomInt(0, remaining);
                    // 将随机道的题加入
                    selectQuestions.add(questions.get(index));
                    // 一处选中题
                    questions.remove(index);
                }
            } else
                selectQuestions = questions.stream().limit(extractCount).collect(Collectors.toList());
        }

        UserPsychAssessmentRecordDO record = new UserPsychAssessmentRecordDO();
        record.setUserId(loginUserId).setTitle("首次测评");
        userPsychAssessmentRecordMapper.insert(record);

        Long recordId = record.getId();
        for (PsychQuestionDO selectQuestion : selectQuestions) {
            UserPsychQuestionRecordDO answerRecord = BeanUtils.toBean(selectQuestion, UserPsychQuestionRecordDO.class);
            answerRecord.setRecordId(recordId);
            answerRecord.setQuestionId(selectQuestion.getId());
            answerRecord.setCreator(null);
            answerRecord.setCreateTime(null);
            answerRecord.setUpdater(null);
            answerRecord.setUpdateTime(null);
            answerRecord.setId(null);
            userPsychQuestionRecordMapper.insert(answerRecord);
        }

        return recordId;
    }

    @Override
    @Transactional
    public Long userAnswerQuestion(UserAnswerQuestionReqVO answerReqVO, Long loginUserId) {
        UserPsychQuestionRecordDO questionRecord = userPsychQuestionRecordMapper.selectById(answerReqVO.getId());
        if (Objects.isNull(questionRecord))
            throw exception(USER_PSYCH_QUESTION_RECORD_NOT_EXISTS);

        UserPsychAssessmentRecordDO assessmentRecord = userPsychAssessmentRecordMapper.selectById(questionRecord.getRecordId());
        if (Objects.isNull(assessmentRecord))
            throw exception(USER_PSYCH_QUESTION_RECORD_NOT_EXISTS);

        Boolean done = assessmentRecord.getDone();
        if (done)
            throw exception(USER_PSYCH_QUESTION_RECORD_IS_DONE);

        if (!assessmentRecord.getUserId().equals(loginUserId))
            throw exception(USER_PSYCH_QUESTION_RECORD_USER_NOT_MATCH);

        List<PsychQuestionDO.Option> optionList = questionRecord.getOptionList();

        String answer = answerReqVO.getAnswer();
        PsychQuestionDO.Option selectOption = optionList.stream().filter(o -> answer.equals(o.getSelTitle())).findFirst().orElse(null);
        if (Objects.isNull(selectOption))
            throw exception(USER_PSYCH_QUESTION_RECORD_ANSWER_NOT_EXISTS);

        // 更新题目答案
        userPsychQuestionRecordMapper.update(Wrappers.<UserPsychQuestionRecordDO>lambdaUpdate()
                .eq(UserPsychQuestionRecordDO::getId, questionRecord.getId())
                .set(UserPsychQuestionRecordDO::getAnswer, answer)
                .set(UserPsychQuestionRecordDO::getScore, selectOption.getScore()));

        // 判断用户是否答完全部题目
        List<UserPsychQuestionRecordDO> answerQuestionRecords = userPsychQuestionRecordMapper.selectList(UserPsychQuestionRecordDO::getRecordId, questionRecord.getRecordId());
        boolean noAnswerQuestion = answerQuestionRecords.stream().allMatch(q -> StrUtil.isNotBlank(q.getAnswer()));
        // 为true，则代表没有未答的题目了，则更新记录状态，并计算总分数
        if (noAnswerQuestion) {
            // 计算总分数
            int totalScore = answerQuestionRecords.stream().mapToInt(UserPsychQuestionRecordDO::getScore).sum();

            // 获取用户是否是首次答题
            boolean isFirst = userPsychAssessmentRecordMapper.selectCount(UserPsychAssessmentRecordDO::getUserId, loginUserId) == 1;

            String riskLevel = null;
            // 非首次答题
            if (!isFirst){
                // 根据用户当前的答题的题目，查出题库的类型
                PsychQuestionDO questionDO = psychQuestionMapper.selectById(answerReqVO.getId());
                if (null == questionDO)
                    throw exception(PSYCH_QUESTION_BANK_NOT_EXISTS);
                PsychQuestionBankDO questionBankDO = psychQuestionBankMapper.selectById(questionDO.getBankId());
                if (null == questionBankDO)
                    throw exception(PSYCH_QUESTION_BANK_NOT_EXISTS);

                ConfigRiskLevelDO configRiskLevel = configRiskLevelMapper.selectOne(Wrappers.<ConfigRiskLevelDO>lambdaQuery()
                        .eq(ConfigRiskLevelDO::getRiskLevel, questionBankDO.getRiskLevel())
                        .le(ConfigRiskLevelDO::getMinVal, totalScore)
                        .ge(ConfigRiskLevelDO::getMaxVal, totalScore)
                        .orderByAsc(ConfigRiskLevelDO::getId).last("LIMIT 1"));
                if (Objects.isNull(configRiskLevel))
                    throw exception(CONFIG_RISK_LEVEL_NOT_EXISTS_APP);
                riskLevel = configRiskLevel.getRiskLevel();
            }

            // 更新记录状态
            userPsychAssessmentRecordMapper.update(Wrappers.<UserPsychAssessmentRecordDO>lambdaUpdate()
                    .eq(UserPsychAssessmentRecordDO::getId, assessmentRecord.getId())
                    .set(UserPsychAssessmentRecordDO::getDone, true)
                    .set(UserPsychAssessmentRecordDO::getTotalScore, totalScore)
                    .set(UserPsychAssessmentRecordDO::getRiskLevel, riskLevel));

            // 判断是否是首次答题，若是，则判断用户设置的测评分数
            if (isFirst) {
                // 获取用户设置的分数阈值
                BasicConfigDO basicConfigDO = basicConfigMapper.selectById(1L);
                if (Objects.isNull(basicConfigDO))
                    throw exception(BASIC_CONFIG_NOT_EXISTS);

                LambdaQueryWrapper<PsychQuestionBankDO> wrapper = Wrappers.<PsychQuestionBankDO>lambdaQuery()
                        .eq(PsychQuestionBankDO::getStatus, 0)
                        .nested(w -> w.isNull(PsychQuestionBankDO::getValidTime).or().ge(PsychQuestionBankDO::getValidTime, LocalDateTime.now()))
                        .orderByDesc(PsychQuestionBankDO::getIsTop, BaseDO::getUpdateTime);

                Integer answerScore = basicConfigDO.getAnswerScore();
                // 不要总数（废弃）
                //int totalQuestion = 0;
                // 随机中低风险题库 20道
                if (totalScore <= answerScore) {
                    wrapper.nested(w -> w.eq(PsychQuestionBankDO::getRiskLevel, 1).or().eq(PsychQuestionBankDO::getRiskLevel, 2));
                    //totalQuestion = 20;
                }else { // 随机高风险题库40道
                    wrapper.eq(PsychQuestionBankDO::getRiskLevel, 3);
                    //totalQuestion = 40;
                }

                // 根据条件查询题库
                List<PsychQuestionBankDO> banks = psychQuestionBankMapper.selectList(wrapper);
                if (CollUtil.isEmpty(banks))
                    throw exception(PSYCH_QUESTION_BANK_NOT_EXISTS);
                List<PsychQuestionDO> selectQuestions = new ArrayList<>();
                for (PsychQuestionBankDO bank : banks) {
                    // 查询当前题库的试题
                    List<PsychQuestionDO> questions = psychQuestionMapper.selectList(PsychQuestionDO::getBankId, bank.getId());
                    if (CollUtil.isNotEmpty(questions)){
                        // 如果当前题库里的题目 <= 待取数量，则直接将这几道题返回
                        Integer extractCount = bank.getExtractCount();
                        if (questions.size() <= extractCount)
                            selectQuestions.addAll(questions);
                        else {
                            Boolean extractType = bank.getExtractType();
                            if (extractType) {
                                // 根据提取数量遍历
                                for (int i = 0; i < extractCount; i++) {
                                    // 计算剩余的提取次数
                                    int remaining = extractCount - i;
                                    // 计算随机数
                                    int index = RandomUtil.randomInt(0, remaining);
                                    // 将随机道的题加入
                                    selectQuestions.add(questions.get(index));
                                    // 一处选中题
                                    questions.remove(index);
                                }
                            } else
                                selectQuestions.addAll(questions.stream().limit(extractCount).collect(Collectors.toList()));
                        }
                    }
                }

                // 若题目数 > totalQuestion，则再从这些题库中移除多余的数（废弃）
                /*if (selectQuestions.size() > totalQuestion) {
                    int waitDelCount = selectQuestions.size() - totalQuestion;
                    for (int i = 0; i < waitDelCount; i++) {
                        selectQuestions.remove(RandomUtil.randomInt(0, selectQuestions.size()));
                    }
                }*/

                UserPsychAssessmentRecordDO record = new UserPsychAssessmentRecordDO();
                record.setUserId(loginUserId).setTitle("二次测评");
                userPsychAssessmentRecordMapper.insert(record);

                Long recordId = record.getId();
                for (PsychQuestionDO selectQuestion : selectQuestions) {
                    UserPsychQuestionRecordDO answerRecord = BeanUtils.toBean(selectQuestion, UserPsychQuestionRecordDO.class);
                    answerRecord.setRecordId(recordId);
                    answerRecord.setQuestionId(selectQuestion.getId());
                    answerRecord.setCreator(null);
                    answerRecord.setCreateTime(null);
                    answerRecord.setUpdater(null);
                    answerRecord.setUpdateTime(null);
                    answerRecord.setId(null);
                    userPsychQuestionRecordMapper.insert(answerRecord);
                }
                return record.getId();
            } else {
                // 赠送用户答题积分
                UserPointsRecordSaveReqVO reqVO = new UserPointsRecordSaveReqVO();
                reqVO.setUserId(loginUserId).setCls(CLS4.getValue()).setType(true).setObtainedPoints(2).setTitle("压力自测，完成整套测试");
                userPointsRecordService.createUserPointsRecord(reqVO);
            }
        }
        return null;
    }

    @Override
    public PageResult<AppUserPsychAssessmentRecordSimpleRespVO> appGetRecordPage(PageParam pageParam, Long loginUserId) {
        // MyBatis Plus 查询
        IPage<AppUserPsychAssessmentRecordSimpleRespVO> mpPage = MyBatisUtils.buildPage(pageParam);
        // 转换返回
        List<AppUserPsychAssessmentRecordSimpleRespVO> respList = userPsychAssessmentRecordMapper.selectCustomPage(mpPage, loginUserId);
        for (AppUserPsychAssessmentRecordSimpleRespVO respVO : respList) {
            respVO.setRiskLevelName(DictFrameworkUtils.parseDictDataLabel("business_psych_question_risk_level", respVO.getRiskLevel()));
        }
        mpPage.setRecords(respList);

        return new PageResult<>(mpPage.getRecords(), mpPage.getTotal());
    }

    @Override
    public AppUserPsychAssessmentRecordDetailRespVO appGetUserPsychAssessmentRecord(Long id, Long loginUserId) {
        UserPsychAssessmentRecordDO userPsychAssessmentRecordDO = userPsychAssessmentRecordMapper.selectByUserId(id, loginUserId);
        if (userPsychAssessmentRecordDO == null)
            throw exception(USER_PSYCH_QUESTION_RECORD_NOT_EXISTS);

        UserDO userDO = bizUserMapper.selectById(loginUserId);
        if (userDO == null)
            throw exception(USER_NOT_EXISTS);

        AppUserPsychAssessmentRecordDetailRespVO respVO = BeanUtils.toBean(userPsychAssessmentRecordDO, AppUserPsychAssessmentRecordDetailRespVO.class);
        List<UserPsychQuestionRecordDO> answerQuestions = userPsychQuestionRecordMapper.selectListByRecordId(id);
        respVO.setAnswerQuestions(BeanUtils.toBean(answerQuestions, AppUserPsychQuestionRecordDetailRespVO.class));
        respVO.setRiskLevelName(DictFrameworkUtils.parseDictDataLabel("business_psych_question_risk_level", respVO.getRiskLevel()));

        ConfigRiskLevelDO configRiskLevel = configRiskLevelMapper.selectOne(Wrappers.<ConfigRiskLevelDO>lambdaQuery()
                .eq(ConfigRiskLevelDO::getRiskLevel, userPsychAssessmentRecordDO.getRiskLevel())
                .le(ConfigRiskLevelDO::getMinVal, userPsychAssessmentRecordDO.getTotalScore())
                .ge(ConfigRiskLevelDO::getMaxVal, userPsychAssessmentRecordDO.getTotalScore())
                .orderByAsc(ConfigRiskLevelDO::getId).last("LIMIT 1"));
        if (configRiskLevel != null) {
            respVO.setResultContent(configRiskLevel.getContent());
            if ("3".equals(configRiskLevel.getRiskLevel())) {
                Long schoolId = userDO.getSchoolId();
                if (schoolId != null){
                    SchoolDO schoolDO = schoolMapper.selectById(schoolId);
                    if (schoolDO != null)
                        respVO.setCenterHotline(schoolDO.getMobile());
                }
            }
        }
        return respVO;
    }

    @Override
    public AppNeedAnswerRespVO needAnswer(Long loginUserId) {
        AppNeedAnswerRespVO respVO = new AppNeedAnswerRespVO();
        // 判断当前用户是否已经答过首套试题
        UserPsychAssessmentRecordDO record = userPsychAssessmentRecordMapper.selectOne(Wrappers.<UserPsychAssessmentRecordDO>lambdaQuery()
                .eq(UserPsychAssessmentRecordDO::getUserId, loginUserId).last("LIMIT 1"));

        respVO.setFirstAnswer(record != null && record.getDone());

        UserPsychAssessmentRecordDO lastRecord = userPsychAssessmentRecordMapper.selectOne(Wrappers.<UserPsychAssessmentRecordDO>lambdaQuery()
                .eq(UserPsychAssessmentRecordDO::getUserId, loginUserId)
                .eq(UserPsychAssessmentRecordDO::getDone, 0)
                .orderByDesc(BaseDO::getCreateTime).last("LIMIT 1"));
        respVO.setUnfinishedQuestion(lastRecord != null && !lastRecord.getDone());
        if (respVO.getUnfinishedQuestion()) {
            respVO.setUnfinishedRecordId(lastRecord != null ? lastRecord.getId() : null);
        }
        return respVO;
    }

    @Override
    public Long restart(Long loginUserId) {
        // 查询用户答题记录
        List<UserPsychAssessmentRecordDO> records = userPsychAssessmentRecordMapper.selectList(UserPsychAssessmentRecordDO::getUserId, loginUserId);
        if (CollUtil.isNotEmpty(records)){
            for (UserPsychAssessmentRecordDO record : records) {
                // 删除用户的答题记录
                userPsychAssessmentRecordMapper.deleteById(record.getId());
                userPsychQuestionRecordMapper.delete(UserPsychQuestionRecordDO::getRecordId, record.getId());
            }
        }

        return appUserCreate(loginUserId);
    }

    @Override
    public Long restartUnfinished(Long loginUserId) {
        // 查询用户答题记录
        List<UserPsychAssessmentRecordDO> records = userPsychAssessmentRecordMapper.selectList(UserPsychAssessmentRecordDO::getUserId, loginUserId);
        if (CollUtil.isNotEmpty(records)){
            for (UserPsychAssessmentRecordDO record : records) {
                // 查询所有题目
                List<UserPsychQuestionRecordDO> questions = userPsychQuestionRecordMapper.selectList(UserPsychQuestionRecordDO::getRecordId, record.getId());
                // 计算总分数
                int totalScore =  questions.stream().filter(q -> Objects.nonNull(q.getScore())).mapToInt(UserPsychQuestionRecordDO::getScore).sum();
                // 更新总分数
                userPsychAssessmentRecordMapper.update(UserPsychAssessmentRecordDO::getId, record.getId(), UserPsychAssessmentRecordDO::getTotalScore, totalScore);
                // 删除用户的答题记录
                userPsychAssessmentRecordMapper.deleteById(record.getId());
                userPsychQuestionRecordMapper.delete(UserPsychQuestionRecordDO::getRecordId, record.getId());
            }
        }

        return appUserCreate(loginUserId);
    }

    private void validateUserPsychQuestionRecordExists(Long id) {
        if (userPsychQuestionRecordMapper.selectById(id) == null) {
            throw exception(USER_PSYCH_QUESTION_RECORD_NOT_EXISTS);
        }
    }

    private void deleteUserPsychQuestionRecordByRecordId(Long recordId) {
        userPsychQuestionRecordMapper.deleteByRecordId(recordId);
    }

    private void deleteUserPsychQuestionRecordByRecordIds(List<Long> recordIds) {
        userPsychQuestionRecordMapper.deleteByRecordIds(recordIds);
    }

}